Skip to content

ci: cross-compile aarch64-apple-darwin from Linux (drop macos-latest lane)#771

Merged
zackees merged 1 commit into
mainfrom
feat/linux-cross-mac-arm64
Jun 28, 2026
Merged

ci: cross-compile aarch64-apple-darwin from Linux (drop macos-latest lane)#771
zackees merged 1 commit into
mainfrom
feat/linux-cross-mac-arm64

Conversation

@zackees

@zackees zackees commented Jun 28, 2026

Copy link
Copy Markdown
Member

Summary

Replaces the macos-latest runner for the aarch64-apple-darwin release lane with the existing ubuntu-latest runner already shared by every other target. Uses soldr + cargo-zigbuild + soldr's managed Apple SDK to produce real Mach-O arm64 binaries from Linux x86_64. Removes the last cross-platform-runner dependency from the release matrix.

What landed

  • .github/workflows/release-auto.yml — aarch64-apple-darwin lane swaps to ubuntu-latest + new mac_cross_linux: true flag
  • .github/workflows/template_native_build.yml — adds the mac_cross_linux boolean + matching build / PyO3 / staging / strip branches
  • ci/docker-mac-arm64-cross/ — minimal ubuntu:24.04-based docker image + build.sh that reproduces the GHA flow locally and asserts via file(1) that all three artifacts are valid Mach-O arm64. The "NO CHEATING" local-validation gate.

How it was validated

Local docker run against current main:

staging/fbuild:          Mach-O 64-bit arm64 executable
staging/fbuild-daemon:   Mach-O 64-bit arm64 executable
staging/_native.abi3.so: Mach-O 64-bit arm64 dynamically linked shared library

Sizes: 23 MB / 25 MB / 14 MB — comparable to the macOS-native lane.

Test plan

  • Local docker validation: 3 Mach-O arm64 artifacts produced and verified by file(1)
  • Trigger GHA release; verify the aarch64-apple-darwin matrix entry succeeds on ubuntu-latest
  • Verify uploaded artifacts in the resulting GitHub Release are unchanged in shape (same binaries, same _native.abi3.so layout)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added support for building macOS ARM64 release artifacts from Linux, improving build flexibility and speed.
    • Enabled cross-platform packaging for the app’s command-line tools and Python extension on the same release lane.
    • Added a containerized workflow for reproducing the macOS ARM64 build process locally.
  • Documentation

    • Added setup and usage instructions for the new cross-build container, including verification steps for generated binaries.

…lane)

Replaces the `macos-latest` runner for the `aarch64-apple-darwin`
release lane with the existing `ubuntu-latest` runner already shared
by every other target. The Linux runner uses soldr +
cargo-zigbuild + soldr's managed Apple SDK to produce real Mach-O
arm64 binaries — closing the last cross-platform-runner dependency
in the release matrix.

## What landed

* `.github/workflows/release-auto.yml` — `aarch64-apple-darwin` lane
  swaps `runner: macos-latest` for `runner: ubuntu-latest` plus the
  new `mac_cross_linux: true` flag.

* `.github/workflows/template_native_build.yml` — adds the
  `mac_cross_linux: true` boolean input + the matching build / PyO3 /
  staging / strip branches. When set:
    - `soldr prepare --target aarch64-apple-darwin` fetches the Apple
      SDK ahead of cargo so the SDKROOT export is debuggable
      independently
    - `soldr cargo zigbuild --release --target aarch64-apple-darwin`
      builds `fbuild-cli` + `fbuild-daemon`
    - `PYO3_NO_PYTHON=1 soldr cargo zigbuild ...` builds the
      `fbuild-python` PyO3 extension with the same target-dir layout
      the macOS native lane produced (no rename needed in stage step)
    - strip step is a no-op (Linux's binutils `strip` would silently
      corrupt a Mach-O; the binaries ship unstripped at ~25 MB each)

* `ci/docker-mac-arm64-cross/` — a minimal `ubuntu:24.04`-based docker
  image + `build.sh` that reproduces the GHA flow locally and asserts
  via `file(1)` that all three output artifacts are
  `Mach-O 64-bit ... arm64`. The "NO CHEATING" gate that locked the
  workflow design.

## How it was validated

Local run inside the docker image, against the current tip of
FastLED/fbuild#main:

```
staging/fbuild:          Mach-O 64-bit arm64 executable
staging/fbuild-daemon:   Mach-O 64-bit arm64 executable
staging/_native.abi3.so: Mach-O 64-bit arm64 dynamically linked shared library
```

Sizes: 23 MB / 25 MB / 14 MB — comparable to the macOS-native lane.

## Known soft warnings (non-blocking)

* `rust-objcopy` fails to load `libLLVM.so` during the strip-debuginfo
  post-link step on aarch64-apple-darwin — cargo's `profile.release.strip`
  knob calls rust-objcopy which expects libLLVM next to the rustc binary.
  Cargo treats this as a warning and the binaries are produced
  correctly. soldr#934's `llvm-tools-preview` work covers this when
  the catalogue ingest cycle wires it up.
* `soldr prepare` warns about a failed internal `rustup target add` —
  cosmetic, the explicit `soldr rustup target add` in build.sh already
  added the target. Tracked separately as a soldr bug.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2dfee06d-ec33-4cc8-bd53-054b3295313d

📥 Commits

Reviewing files that changed from the base of the PR and between 15551a6 and b2e6368.

📒 Files selected for processing (5)
  • .github/workflows/release-auto.yml
  • .github/workflows/template_native_build.yml
  • ci/docker-mac-arm64-cross/Dockerfile
  • ci/docker-mac-arm64-cross/README.md
  • ci/docker-mac-arm64-cross/build.sh

📝 Walkthrough

Walkthrough

The aarch64-apple-darwin release lane is moved from a macOS runner to ubuntu-latest using soldr + cargo-zigbuild for cross-compilation. A new mac_cross_linux boolean flag threads through the release matrix and the native build template to gate Apple SDK preparation, zigbuild invocations, artifact staging, and strip skipping. A local Docker simulator (ci/docker-mac-arm64-cross/) with build.sh and README is added to reproduce this lane without GitHub Actions.

Changes

aarch64-apple-darwin Linux Cross-Compile Lane

Layer / File(s) Summary
Release matrix: switch aarch64 to ubuntu + mac_cross_linux flag
.github/workflows/release-auto.yml
aarch64-apple-darwin matrix entry changed from macos-latest to ubuntu-latest with mac_cross_linux: true; the flag is passed into the template workflow call.
template_native_build: mac_cross_linux input and build/stage/strip branches
.github/workflows/template_native_build.yml
Declares mac_cross_linux boolean input; adds soldr prepare step for Apple SDK; routes fbuild-cli, fbuild-daemon, and fbuild-python through soldr cargo zigbuild; copies lib_native.dylib into staging/_native.abi3.so; skips binary stripping for Mach-O.
Docker image for local cross simulation
ci/docker-mac-arm64-cross/Dockerfile, ci/docker-mac-arm64-cross/README.md
New ubuntu:24.04-based Dockerfile that installs uv, pinned soldr binaries, cargo-zigbuild, and zig, setting required env defaults. README explains purpose, build/run commands, and the Mach-O validation check.
build.sh: cross-compile, stage, and validate
ci/docker-mac-arm64-cross/build.sh
Script bootstraps Rust via soldr, pre-fetches Apple SDK, builds all three crates with soldr cargo zigbuild, stages artifacts (renaming dylib to _native.abi3.so), and validates each is a Mach-O ARM64 binary via file(1).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • FastLED/fbuild#760: Modifies the same release-auto.yml and template_native_build.yml for cross-compiling the aarch64-apple-darwin lane from Linux with cargo zigbuild, including the same lib_native.dylibstaging/_native.abi3.so staging pattern.
  • FastLED/fbuild#153: Introduces soldr integration into template_native_build.yml build workflows, directly underpinning the soldr prepare and soldr cargo zigbuild calls added in this PR.
  • FastLED/fbuild#16: Overlaps on the cross-compilation staging of _native.abi3.so and Mach-O-specific strip logic in template_native_build.yml for other cross targets.

Poem

🐇 Hop hop, no Mac in sight,
Ubuntu builds the ARM just right,
zigbuild soars, the Apple SDK found,
Mach-O binaries, arm64-bound!
"NO CHEATING," the file check cries—
A rabbit's cross-compile, Linux-skies! ✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/linux-cross-mac-arm64

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@zackees zackees merged commit a8b001c into main Jun 28, 2026
87 of 91 checks passed
zackees added a commit that referenced this pull request Jun 28, 2026
Triggers the autonomous release workflow. First release that
cross-compiles `aarch64-apple-darwin` from `ubuntu-latest` instead
of running on a `macos-latest` runner (#771).

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
zackees added a commit that referenced this pull request Jun 28, 2026
setup-soldr@v0.9.62 defaults to soldr 0.7.51, which predates the
\`soldr prepare\` builtin used by the new \`mac_cross_linux: true\` lane
(landed in #771). The lane was failing with
\`soldr: tool not found: prepare: not found on crates.io\` — soldr 0.7.51
treated \`prepare\` as a tool name and tried to fetch it from crates.io.

Fix:
* Bump action pin v0.9.62 → v0.9.63 (which defaults to 0.7.59)
* Pin \`version: "0.7.59"\` explicitly so a future action default change
  doesn't silently shift build behavior.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@fastled-project-sync fastled-project-sync Bot moved this to Triage in FastLED Tracker Jun 28, 2026
zackees added a commit that referenced this pull request Jun 28, 2026
)

soldr#1006 Lane 3. Closes the easiest remaining gap from the meta:
\`x86_64-apple-darwin\` is now built from \`ubuntu-latest\` via the same
\`mac_cross_linux: true\` template branch the arm64 lane already uses
(landed in #771). Soldr's apple_sdk fetcher auto-picks the
\`darwin-x86_64\` thin shape when the target triple matches, and
\`cargo zigbuild --target x86_64-apple-darwin\` resolves SDKROOT +
frameworks identically.

Net effect:
- fbuild's release matrix gains a 5th target (mac Intel) for the same
  per-release runner cost (just adds another ubuntu-latest job).
- Zero \`macos-latest\` runners left in the matrix — both Apple
  targets cross-compile from Linux.

## Docker harness changes

* Renamed \`ci/docker-mac-arm64-cross/\` → \`ci/docker-mac-cross/\` since
  the same image now validates both Apple targets.
* \`build.sh\` takes a target as positional arg or \`TARGET=\` env var
  (default: aarch64-apple-darwin); per-target arch verification —
  \`arm64|aarch64\` for arm64 lane, \`x86_64\` for Intel lane.
* Image tag bumped from \`fbuild-mac-arm64-cross\` →
  \`fbuild-mac-cross\` to match.

## Test plan
- [x] Build docker image
- [ ] Run \`bash ci/docker-mac-cross/build.sh x86_64-apple-darwin\`,
      verify 3 Mach-O x86_64 artifacts under staging/
- [ ] Trigger a release via version bump; verify new matrix entry
      ships \`fbuild-v<ver>-x86_64-apple-darwin.tar.gz\`

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Triage

Development

Successfully merging this pull request may close these issues.

1 participant